package com.lidong.zc.databasemodel.mapper;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import com.lidong.zc.databasemodel.entity.mybatis.SqlDTO;
import com.lidong.zc.databasemodel.entity.mybatis.LowerKeyMap;
import com.lidong.zc.databasemodel.entity.mybatis.UpperKeyMap;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.springframework.util.StringUtils;

/**
 * @author LiDong
 * @version 1.0.0
 * @createTime 12/6/2022 8:40 AM
 */
@Mapper
public interface CommonMapper {

    /**
     * @param sqlDTO sqlDTO
     * @return itn
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    int countBySql(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     */
    @UpdateProvider(type = SqlProvider.class, method = "modifySql")
    void executeBySql(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     * @return List
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<String> listString(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     * @return List
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<Integer> listInteger(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     * @return List
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<BigDecimal> listBigDecimal(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     * @return List
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<Map<String, Object>> listMap(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     * @return List
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<UpperKeyMap> listUpperKeyMap(SqlDTO sqlDTO);

    /**
     * @param sqlDTO sqlDTO
     * @return List
     */
    @SelectProvider(type = SqlProvider.class, method = "selectSql")
    List<LowerKeyMap> listLowerKeyMap(SqlDTO sqlDTO);

    class SqlProvider {
        public String selectSql(SqlDTO sqlDTO) {
            String sql = sqlDTO.getSql();
            if (!StringUtils.hasText(sql)) {
                throw new RuntimeException("SQL语句为null，无法执行");
            }
            String sqlStart = sql.trim().substring(0, 6);
            if (!"select".equalsIgnoreCase(sqlStart) && !"PRAGMA".equals(sqlStart)) {
                throw new RuntimeException("非法的SQL语句");
            }
            if (sql.contains(";")) {
                throw new RuntimeException("非法的SQL语句");
            }
            return sql;
        }

        public String modifySql(SqlDTO sqlDTO) {
            return sqlDTO.getSql();
        }
    }

}
